package com.dyh.quickdemozwei.compObj;

import com.dyh.quickdemozwei.compObj.comp.DomainInputCompose;
import com.dyh.quickdemozwei.compObj.comp.DomainOutputCompose;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;

public class CompObject {


//    Map<Class, List<Compose>> cls2compose = new HashMap<>();
    Map<Class,Map<String,Object>> data = new HashMap<>();

    public Consumer<CompObject> consumer;

    static final String defaultName(Class cls){
        return cls.getCanonicalName();
    }

    public <T> T  getCompose(Class<T> cls){
        return Optional.ofNullable(data.get(cls))
                .map(e->e.get(defaultName(cls)))
                .map(cls::cast)
                .orElse(null);
    }

    public <T> T  getCompose(String name,Class<T> cls){
        return Optional.ofNullable(data.get(cls))
                .map(e->e.get(name))
                .map(cls::cast)
                .orElse(null);
    }

    public <T> Collection<T> getComposes(Class<T> cls){
        return Optional.ofNullable(data.get(cls))
                .map(e->e.values())
                .map(e->(Collection<T>)e)
                .orElse(null);
    }

    public <T> T getInput(){
        return Optional.ofNullable(getCompose(DomainInputCompose.class)).map(e->e.getData()).map(e->(T)e).orElse(null);
    }

    public <T> T getInput(String name){
        return Optional.ofNullable(getCompose(name,DomainInputCompose.class)).map(e->e.getData()).map(e->(T)e).orElse(null);
    }

    public <T> T getOutput(String name){
        return Optional.ofNullable(getCompose(name,DomainOutputCompose.class)).map(e->e.getData()).map(e->(T)e).orElse(null);

    }

    public <T> T getOutput(){
        return Optional.ofNullable(getCompose(DomainOutputCompose.class)).map(e->e.getData()).map(e->(T)e).orElse(null);
    }

    public <T> void  setOutput(T t){
        add(DomainOutputCompose.from(t));
//        Optional.ofNullable(getCompose(DomainOutputCompose.class))
////                .ifPresent(x->x.setData(t));
    }

    public  void add(Object compose){
        data.computeIfAbsent(compose.getClass(),x->new HashMap<>())
                .put(defaultName(compose.getClass()),compose);
    }

    public void add(String name , Object compose){
        data.computeIfAbsent(compose.getClass(),x->new HashMap<>())
                .put(name,compose);
    }

    public void setScript(Consumer<CompObject> consumer){
        this.consumer = consumer;
    }

}
